home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 11 - 1995 / 11.02 Feb 95 / Yenta / Application Shellƒ / CPPYenta.cp next >
Encoding:
Text File  |  1996-04-04  |  10.7 KB  |  374 lines  |  [TEXT/KAHL]

  1. /********************************************************* DEFINITION
  2.     DATE:    9/26/93
  3.     AUTHOR: Eric R. Rosé
  4.     
  5.     CLASS:  CPPYenta
  6.     
  7.     SUPERCLASS: CPPApplication
  8.     
  9.         This C++ class defines the backbone for the Yenta Application.
  10.         
  11. ********************************************************************/
  12.  
  13. #include "CPPYenta.h"
  14. #include "CPPSendWindow.h"
  15. #include <CPPTaskManager.h>
  16. #include "CPPMessageWindow.h"
  17. #include "CPPYentaMenuBar.h"
  18. #include "CPPPrefsWindow.h"
  19. #include "CPPYentaAboutBox.h"
  20. #include "MyCommands.h"
  21. #include <CPPWindowManager.h>
  22. #include <CPPMaBell.h>
  23. #include <CPPZone411.h>
  24. #include <CPPNode411.h>
  25. #include <CPPNodeInfo.h>
  26. #include "CPPSpawnConfirmTask.h"
  27. #include "CPPSpawnZoneTask.h"
  28. #include "CPPYListenTask.h"
  29. #include <Commands.h>
  30. #include <CPPSound.h>
  31. #include <CPPDRequest.h>
  32. #include <Script.h>
  33. #include <StringTools.h>
  34. #include <ToolboxTools.h>
  35. #include <MemoryTools.h>
  36.  
  37.  
  38. #include    <CPPStringList.h>
  39. #include    <CPPObjectList.h>
  40. #include    <CPPList.h>
  41. #include    <PPCToolbox.h>
  42.  
  43. /*-----------------------------------------------------------------*/
  44. /*--------------------- APPLICATION GLOBALS -----------------------*/
  45. /*-----------------------------------------------------------------*/
  46.  
  47.     CPPNodeInfo     *gOurIdentity;
  48.     CPPZoneList        *gZoneList;    // pointer to the send dialog's zone list
  49.     CPPUserList        *gUserList;    // pointer to the send dialog's user list
  50.     CPPList            *gTalkText;    // incoming message queue
  51.     CPPSpawnConfirmTask    *gStartConfirmUsersTask = NULL;
  52.     CPPSpawnZoneTask    *gStartScanZoneTask = NULL;
  53.     PPCPortRefNum    gOurPort;
  54.     CPPSound        *gIncomingSound;
  55.     CPPSound        *gLogonSound;
  56.     CPPMaBell        *gMaBell;
  57.     CPPTaskManager    *gSlaveDriver;
  58.     PrefsData        gPrefsInfo = {0, 0, TRUE, TRUE};
  59.     StringPtr        gReplyString = NULL;
  60.     CPPSendWindow        *gSendWindow;
  61.     CPPMessageWindow    *gMessageWindow;
  62.     StringPtr            gZoneName = NULL; 
  63.     StringPtr        gAppName = "\pYenta";
  64.                         
  65.     extern    CPPMenuBar            *gMenuBar;
  66.     extern    CPPWindowManager    *gWindowManager;
  67.     
  68. /*-----------------------------------------------------------------*/
  69. /*--------------------- FORWARD DECLARATIONS ----------------------*/
  70. /*-----------------------------------------------------------------*/
  71.     
  72.     void    RecordOurAddress (CPPObject *TheObject);
  73.     void    SetStatusMessage (StringPtr NewMessage, Boolean MakeCopy);
  74.     StringPtr    ShortName     (CPPNodeInfo *theNode);
  75.     
  76. /*-----------------------------------------------------------------*/
  77. /*-----------------------------------------------------------------*/
  78. /*-----------------------------------------------------------------*/
  79.     
  80.     void    SetStatusMessage (StringPtr NewMessage, Boolean MakeCopy)
  81.     /* set the message in the send window's status box */
  82.     {
  83.         gSendWindow->SetStatusMessage (NewMessage, MakeCopy);
  84.     }
  85.  
  86. /*-----------------------------------------------------------------*/
  87.  
  88.     void    RecordOurAddress (CPPObject *TheObject)
  89.     /* use this completion routine to store our address */
  90.     {
  91.         CPPNode411    *TheTask = (CPPNode411 *)TheObject;
  92.     
  93.         gOurIdentity = TheTask->NthNode(1, TRUE);
  94.     }
  95.  
  96. /*-----------------------------------------------------------------*/
  97.  
  98.     StringPtr    ShortName     (CPPNodeInfo *theNode)
  99.     /* construct a string of the form Name@zone for the given node */
  100.     {
  101.         StringPtr    ObjStr, TypeStr, ZoneStr;
  102.         Str255        STemp;
  103.         Str32        NewTypeName;
  104.         short        i = 1;
  105.         
  106.         if (theNode)
  107.           {
  108.               theNode->GetNodeName (&ObjStr, &TypeStr, &ZoneStr);
  109.             while (((TypeStr[i] & 0x00FF) != 0xA5) && (i <= TypeStr[0]))
  110.               i++;
  111.             CopyString(TypeStr, NewTypeName);
  112.             NewTypeName[0] = i-1;
  113.             PStrCat (255, STemp, 3, NewTypeName, "\p@", ZoneStr);
  114.             return String2String (STemp);
  115.           }
  116.         else
  117.           return NULL;
  118.     }
  119.  
  120. /*-----------------------------------------------------------------*/
  121. /*------------------------ PUBLIC METHODS -------------------------*/
  122. /*-----------------------------------------------------------------*/
  123.  
  124.     CPPYenta::CPPYenta (void) : CPPApplication ()
  125.     {
  126.  
  127.     }
  128.  
  129. /*-----------------------------------------------------------------*/
  130.  
  131.     CPPYenta::~CPPYenta (void)
  132.     {
  133.  
  134.     }
  135.  
  136. /*-----------------------------------------------------------------*/
  137.  
  138.     char    *CPPYenta::ClassName (void)
  139.     {
  140.         return "CPPYenta";
  141.     }
  142.  
  143. /*-----------------------------------------------------------------*/
  144. /*----------------------- PROTECTED METHODS -----------------------*/
  145. /*-----------------------------------------------------------------*/
  146.  
  147.     void CPPYenta::BuildMenuBar (void)
  148.     /* create the application menu bar */
  149.     {
  150.         gMenuBar = new CPPYentaMenuBar ();
  151.     }
  152.  
  153. /*-----------------------------------------------------------------*/
  154.  
  155.     void    CPPYenta::DoApplicationSetup(void)
  156.     /* initialize application globals */
  157.     {
  158.         StringPtr    ObjString = NULL;
  159.         short        MyNodeID, MyZoneID;
  160.         CPPZone411    *ZoneLookup;
  161.         CPPYListenTask    *LTask;
  162.         CPPNode411    *NodeLookup;
  163.         Str32        TypeName;
  164.         OSErr        ErrCode;
  165.     
  166.         this->idleTime = 15;    // set background processing time
  167.  
  168.         if (!DoRequest("\pEnter the name you want to be known by; no more than 30 characters, please",
  169.                          GetChooserName("\pThe Lone Ranger"), &ObjString))
  170.           ExitToShell();
  171.  
  172.         if (*ObjString > 30)
  173.           *ObjString = 30;
  174.  
  175.         // create the appletalk manager and open the needed drivers
  176.         gMaBell = new CPPMaBell (TRUE);
  177.         if ((ErrCode = gMaBell->InitPPCToolbox()) != noErr)
  178.           {
  179.               ErrorAlert (ErrCode, NULL);
  180.               ExitToShell();
  181.           }
  182.         // create the lookup/read/write task manager
  183.         gSlaveDriver = new CPPTaskManager();
  184.  
  185.         // create a ZoneLookup task to find out what zone we are on
  186.         ZoneLookup = new CPPZone411(gSlaveDriver, gMaBell, 17, TRUE);
  187.         gZoneName = ZoneLookup->GetOurZoneName(&ErrCode);
  188.         delete ZoneLookup;
  189.         
  190.         // find out where we are on the network
  191.         if ((ErrCode = GetNodeAddress(&MyNodeID, &MyZoneID)) != noErr)
  192.           {
  193.               ErrorAlert (ErrCode, "\pCan't get our network address.");
  194.               ExitToShell();
  195.           }
  196.         
  197.         // open the port we will use to communicate through
  198.           if ((ErrCode =  gMaBell->OpenCommunicationPort (ObjString, 
  199.                                                           gAppName, 
  200.                                                           &gOurPort)) != noErr)
  201.             {
  202.               ErrorAlert (ErrCode, "\pCan't open a port to communicate with.");
  203.               ExitToShell();
  204.             }
  205.  
  206.             // now that we have opened our communications port, post a 411
  207.             // node lookup task to get our full address
  208.         PStrCat(32, TypeName, 3, ObjString, "\p•", gAppName);
  209.             NodeLookup = new CPPNode411(gSlaveDriver, 5, TRUE);
  210.             NodeLookup->StartNodeLookup ("\p=", TypeName, gZoneName, 1,
  211.                                      RecordOurAddress);
  212.         
  213.             // having opened a port, set up a ConnectionTask to handle
  214.             // communications on that port
  215.             LTask = new CPPYListenTask(gSlaveDriver, 60, TRUE);
  216.             LTask->StartListenTask(gOurPort, NULL);
  217.  
  218.  
  219.         // create the sound objects we will use
  220.         gIncomingSound = new CPPSound (128);
  221.         gLogonSound = new CPPSound (129);
  222.  
  223.         // create the incoming message queue
  224.         gTalkText = new CPPList();
  225.  
  226.         // create and open the application windows        
  227.         gSendWindow = new CPPSendWindow(gWindowManager);
  228.         gMessageWindow = new CPPMessageWindow(gWindowManager);
  229.     }
  230.  
  231. /*-----------------------------------------------------------------*/
  232.  
  233.     void    CPPYenta::DoApplicationShutDown(void)
  234.     /* close the communication port and get rid of the sound objects */
  235.     /* The window manager will clean up our windows */
  236.     {
  237.         OSErr    ErrCode;
  238.         
  239.         delete gSlaveDriver;    // abort any outstanding tasks
  240.                 
  241.         if ((ErrCode = gMaBell->CloseCommunicationPort(gOurPort)) != noErr)
  242.           ErrorAlert (ErrCode, "\pCan't close communication port.");
  243.  
  244.         delete gMaBell;            // close the appletalk manager
  245.  
  246.         // get rid of the sound objects
  247.         delete gIncomingSound;
  248.         delete gLogonSound;
  249.     }
  250.  
  251. /*-----------------------------------------------------------------*/
  252.  
  253.     Boolean    CPPYenta::DoCommand (short commandID)
  254.     {    
  255.         PrefsData    OldPrefs;
  256.         Str255        STemp;
  257.         
  258.         switch (commandID) {
  259.             case kCmdAbout :
  260.                 DoAboutBox();
  261.                 break;
  262.                 
  263.             case kCmdPrefs :
  264.                 OldPrefs = gPrefsInfo;
  265.                 if (DoPrefsWindow (&gPrefsInfo))
  266.                   {
  267.                     if (gPrefsInfo.scanRate != OldPrefs.scanRate)
  268.                       {    // Dequeue the task if we don't want to scan anymore
  269.                           if (gPrefsInfo.scanRate <= 0)
  270.                             gSlaveDriver->RemovePeriodicTask(gStartScanZoneTask, TRUE);
  271.                           else
  272.                             {    
  273.                              if (OldPrefs.scanRate == 0)
  274.                                {        // going from no task to having one
  275.                                  gStartScanZoneTask = 
  276.                                    new CPPSpawnZoneTask (gSlaveDriver, 
  277.                                                          gPrefsInfo.scanRate * 3600, 
  278.                                                           FALSE);
  279.                                 gStartScanZoneTask->StartSpawnZoneTask (NULL);
  280.                                }
  281.                              else    // simply change the rate
  282.                                gStartScanZoneTask->SetPeriod(gPrefsInfo.scanRate * 3600);
  283.                             }
  284.                       }
  285.                     
  286.                     if (gPrefsInfo.confirmRate != OldPrefs.confirmRate)
  287.                       {
  288.                           // Dequeue the task if we don't want the scan anymore
  289.                           if (gPrefsInfo.confirmRate <= 0)
  290.                             gSlaveDriver->RemovePeriodicTask(gStartConfirmUsersTask, TRUE);
  291.                           else
  292.                             {    
  293.                              if (OldPrefs.confirmRate == 0)
  294.                                {    // going from no task to having one
  295.                                  gStartConfirmUsersTask = 
  296.                                    new CPPSpawnConfirmTask (gSlaveDriver, 
  297.                                                               gPrefsInfo.confirmRate * 3600,
  298.                                                               FALSE);
  299.                                 gStartConfirmUsersTask->StartSpawnConfirmTask (NULL);
  300.                                }
  301.                              else  // simply change the rate
  302.                               gStartConfirmUsersTask->SetPeriod(gPrefsInfo.confirmRate * 3600);
  303.                             }
  304.                       }
  305.                   }
  306.                 break;
  307.                 
  308.             case kCmdAutoReply:
  309.                 if (gReplyString)
  310.                   {
  311.                       DisposPtr((Ptr)gReplyString);
  312.                       gReplyString = NULL;
  313.                       gMenuBar->SetCommandText (kCmdAutoReply, "\pAutoReply On…");
  314.                       gSendWindow->RefreshItemStates();
  315.                   }
  316.                 else
  317.                   {
  318.                       if (DoRequest ("\pEnter the string to reply with",
  319.                                      "\pOut of the office", &gReplyString))
  320.                           {
  321.                             // put the chevrons around the reply string
  322.                             PStrCat (255, STemp, 3, "\p«", gReplyString, "\p»");
  323.                             NukePtr(gReplyString);
  324.                             gReplyString = String2String (STemp);
  325.                             
  326.                             gMenuBar->SetCommandText (kCmdAutoReply, "\pAutoReply Off");
  327.                             gSendWindow->RefreshItemStates();
  328.                           }
  329.                   }
  330.                 break;
  331.                 
  332.             case kCmdClose :
  333.                 gWindowManager->FrontWindowObject()->Close();
  334.                 break;
  335.                 
  336.             case kCmdSend :
  337.                 if (gSendWindow)
  338.                   {
  339.                       if (!gSendWindow->WindowVisible())
  340.                         gSendWindow->Show (TRUE);
  341.                       SelectWindow(gSendWindow->GetWindow());
  342.                   }
  343.                 break;
  344.                 
  345.             case kCmdMessage :
  346.                 if (gMessageWindow)
  347.                   {
  348.                       if (!gMessageWindow->WindowVisible())
  349.                         gMessageWindow->Show (TRUE);
  350.                       SelectWindow(gMessageWindow->GetWindow());
  351.                   }
  352.                 break;
  353.                 
  354.             default:
  355.                 return CPPApplication::DoCommand(commandID);
  356.                 break;
  357.         }
  358.     
  359.         return TRUE;
  360.     }
  361.     
  362.  
  363. /*-----------------------------------------------------------------*/
  364.  
  365.     void    CPPYenta::DoAppPeriodicTask (void)
  366.     {
  367.         // check to see if any messages have arrived
  368.         if (gTalkText->GetNumItems() > 0)        
  369.           gSendWindow->ProcessMessageQ();
  370.         
  371.         // handle outstanding lookup calls
  372.         gSlaveDriver->RunPeriodicTasks();    
  373.     }
  374.